package com.et.machine.manager.vm.goods

import android.annotation.SuppressLint
import android.database.ContentObserver
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.et.api.MachineConfig
import com.et.machine.BuildConfig
import com.et.machine.R
import com.et.machine.convert.machineInfo
import com.et.machine.databinding.FragmentGoodsBinding
import com.et.machine.databinding.ItemAllBoxBinding
import com.et.machine.databinding.ItemGoodsListBinding
import com.et.machine.goods.GoodsHelper
import com.et.machine.goods.GoodsHelper.Companion.GOODS_URI
import com.et.machine.goods.globalChannelEntityMap
import com.et.machine.store.ChannelEntity
import com.et.machine.store.DISABLED
import com.et.machine.store.ENABLED
import com.et.machine.store.LACK
import com.et.machine.util.Adapter
import com.et.machine.util.TcpTask
import com.et.util.violationsTrim
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.*
import org.json.JSONObject
import kotlin.collections.set


@Suppress("NAME_SHADOWING")
class GoodsFragment : Fragment() {

    companion object {

        data class Box(var select: Boolean, val box: Int)

        const val BOX_11 = 11
        const val BOX_09 = 9
        const val BOX_08 = 8
        const val BOX_07 = 7
        const val BOX_06 = 6
        const val BOX_01 = 1
        const val BOX_02 = 2
        const val BOX_03 = 3
        const val BOX_04 = 4
        const val BOX_05 = 5
    }

    private val observer: ContentObserver by lazy {
        object : ContentObserver(null) {
            override fun onChange(selfChange: Boolean) {
                super.onChange(selfChange)
                selectedBox?.let {
                    goodsMap.remove(it.box)
                    notifyGoodsInfo(it.box)
                }
            }
        }
    }
    private lateinit var viewModel: GoodsViewModel
    private lateinit var binding: FragmentGoodsBinding
    private val coroutineScope = CoroutineScope(Dispatchers.Main)
    private lateinit var adapterChannel: AdapterUseDiff<ChannelEntity, ItemGoodsListBinding>
    private lateinit var goodsSettingDialogGoods: GoodsInformationDialog
    private var rowsList: MutableList<rows> = mutableListOf()
    private val goodsMap: MutableMap<Int, MutableList<ChannelEntity>> = HashMap()
    private lateinit var company: String
    private lateinit var adapterBox: Adapter<Box, ItemAllBoxBinding>
    private var boxData = mutableListOf<Box>()
    private var selectedBox: Box? = null
    private val goodsHelper: GoodsHelper
        get() {
            return GoodsHelper.getInstance()
        }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = FragmentGoodsBinding.inflate(inflater, container, false).apply {
        binding = this
    }.root

    @SuppressLint("SetTextI18n", "ResourceType", "ClickableViewAccessibility")
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(GoodsViewModel::class.java)

        initClickEvent()
        initBar()
        initBoxAdapter()
        initChannelAdapter()
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initClickEvent() {
        binding.layoutTitle.back.setOnClickListener {
            Navigation.findNavController(it).popBackStack()
        }


        binding.update.setOnTouchListener { view, event ->
            if (event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_MOVE) {
                view.scaleX = 0.9f
                view.scaleY = 0.9f
            } else {
                view.scaleX = 1.0f
                view.scaleY = 1.0f
            }
            false
        }

        binding.update.setOnClickListener {
            coroutineScope.launch {
                viewModel.goodsFromNet().apply {
                    if (success) {
                        Toast.makeText(requireContext(), "商品库同步完成", Toast.LENGTH_LONG).show()
                        MMKV.initialize(context)
                        val kv = MMKV.defaultMMKV()
                        kv.encode("rowsList", content)
                        rows2List(content)
                    } else {
                        Toast.makeText(requireContext(), "商品库同步失败 code:$code", Toast.LENGTH_LONG)
                            .show()
                        Log.d("TAG", content)
                    }
                }
            }

        }
    }

    @SuppressLint("SetTextI18n")
    private fun initBar() {
        // back
        binding.layoutTitle.back.setOnClickListener {
            Navigation.findNavController(it).popBackStack()
        }

        binding.layoutTitle.uuid.text =
            "机器编号：${machineInfo?.uuid}"

        binding.layoutTitle.title.setText(R.string.goods_fragment_label)
    }

    private fun initBoxAdapter() {
        boxData = viewModel.addBoxList()
        boxData[0].apply {
            select = true
            selectedBox = this
        }
        // layout box
        binding.boxListview.also {
            it.adapter = Adapter(
                { view, _, data ->
                    view.box.text = viewModel.box2Name(data.box)
                    if (data.select) {
                        view.box.setBackgroundResource(R.drawable.radio_button_checked_icon)
                        notifyGoodsInfo(data.box)
                    } else {
                        view.box.setBackgroundResource(R.drawable.radio_button_dischecked_icon)
                    }

                    view.box.setOnClickListener {
                        if (selectedBox != null) {
                            selectedBox!!.select = false
                            data.select = true
                        }
                        selectedBox = data
                        adapterBox.notifyDataSetChanged()
                        notifyGoodsInfo(data.box)
                    }

                }, { inflater, viewGroup ->
                    ItemAllBoxBinding.inflate(inflater, viewGroup, false)
                }, boxData
            ).apply {
                adapterBox = this
            }
            it.layoutManager = LinearLayoutManager(requireContext()).apply {
                orientation = LinearLayoutManager.HORIZONTAL
            }
        }
    }

    private fun initChannelAdapter() {
        binding.recyclerview.layoutManager = GridLayoutManager(requireContext(), 3)
        adapterChannel = AdapterUseDiff({ view, _, goodsInfo ->
            view.run {
                name.text = goodsInfo.name
                channel.text = goodsInfo.label
                if (goodsInfo.discount != 100) {
                    discountCard.visibility = View.VISIBLE
                    discount.text = String.format("%.1f折", (goodsInfo.discount / 10f))
                    price.text = String.format(
                        "%.2f",
                        (goodsInfo.priceCent * goodsInfo.discount) / 10000f
                    )
                } else {
                    discountCard.visibility = View.GONE
                    price.text = String.format("%.2f", (goodsInfo.priceCent / 100f))
                }
                if (goodsInfo.image == "No_Image") {
                    image.setImageResource(R.mipmap.wu)
                } else {
                    image.setImageURI(Uri.parse(goodsInfo.image))
                }
                when (goodsInfo.status) {
                    DISABLED -> {
                        disable.visibility = View.VISIBLE
                        bg.setBackgroundResource(R.drawable.radius_bg1)
                    }
                    ENABLED -> {
                        disable.visibility = View.INVISIBLE
                        bg.setBackgroundResource(R.drawable.radius_bg)
                    }
                    LACK -> {
                        disable.visibility = View.VISIBLE
                        bg.setBackgroundResource(R.drawable.radius_bg1)
                    }
                }
                root.setOnClickListener {
                    goodsSettingDialogGoods = GoodsInformationDialog(
                        requireContext(),
                        rowsList,
                        goodsInfo,
                        object : GoodsInformationDialog.OnDialogListener {
                            override fun back(channelEntity: ChannelEntity) {
                                viewModel.downloadImage(
                                    channelEntity,
                                    company,
                                    object : GoodsViewModel.OnDownloadListener {
                                        override fun back(path: String) {
                                            channelEntity.image = path
                                            image.setImageURI(Uri.parse(channelEntity.image))
                                            uploadChannelEntity(channelEntity)
                                        }
                                    })

                                name.text = channelEntity.name
                                if (goodsInfo.discount != 100) {
                                    discountCard.visibility = View.VISIBLE
                                    discount.text =
                                        String.format("%.1f折", (goodsInfo.discount / 10f))
                                    price.text = String.format(
                                        "%.2f",
                                        (goodsInfo.priceCent * goodsInfo.discount) / 10000f
                                    )
                                } else {
                                    discountCard.visibility = View.GONE
                                    price.text = String.format("%.2f", (goodsInfo.priceCent / 100f))
                                }
                                when (channelEntity.status) {
                                    DISABLED -> {
                                        disable.visibility = View.VISIBLE
                                        bg.setBackgroundResource(R.drawable.radius_bg1)
                                    }
                                    ENABLED -> {
                                        disable.visibility = View.INVISIBLE
                                        bg.setBackgroundResource(R.drawable.radius_bg)
                                    }
                                    LACK -> {
                                        disable.visibility = View.VISIBLE
                                        bg.setBackgroundResource(R.drawable.radius_bg1)
                                    }
                                }
                            }
                        })
                    goodsSettingDialogGoods.show()
                }
            }

        }, { inflater, viewGroup ->
            ItemGoodsListBinding.inflate(inflater, viewGroup, false)
        })
        binding.recyclerview.adapter = adapterChannel
        requireContext().contentResolver.registerContentObserver(GOODS_URI, true, observer)
    }


    private fun uploadChannelEntity(channelEntity: ChannelEntity) {
        when (BuildConfig.FLAVOR) {
            "et" -> {
                goodsHelper.add(
                    channelEntity
                )
                GlobalScope.launch(Dispatchers.IO) {
                    TcpTask.uploadGoodsInfo(channelEntity)
                }
                MachineConfig.setChannelInfo(
                    channelEntity.box,
                    channelEntity.channel,
                    if (channelEntity.status == DISABLED) 0xEE else channelEntity.channel,
                    channelEntity.priceCent,
                    false
                )
            }
            "fs" -> {
            }
            "dc" -> {
            }
        }

    }

    private fun notifyGoodsInfo(id: Int) {
        if (goodsMap[id].isNullOrEmpty()) {
            val goods: MutableList<ChannelEntity> = mutableListOf()
            for (channel in 1..48) {
                if (globalChannelEntityMap[id * 1000 + channel] != null) {
                    goods.add(globalChannelEntityMap[id * 1000 + channel]!!)
                } else {
                    goods.add(ChannelEntity().apply {
                        uid = id * 1000 + channel
                        box = id
                        this.channel = channel
                        label = viewModel.getChannelLabel(box, channel)
                        status = DISABLED
                        image = "No_Image"
                    })
                }

            }
            goods.forEach {
                MachineConfig.setChannelInfo(
                    it.box,
                    it.channel,
                    if (it.status == DISABLED) 0xEE else it.channel,
                    it.priceCent,
                    false
                )
            }
            goodsMap[id] = goods
        }
        adapterChannel.dispatchUpdate(
            DiffUtil.calculateDiff(
                GoodsDiffCallBack(adapterChannel.data, goodsMap[id]!!),
                true
            ), goodsMap[id]!!
        )

    }


    override fun onResume() {
        super.onResume()
        MMKV.initialize(context)
        val kv = MMKV.defaultMMKV()
        val rows = kv.decodeString("rowsList", null)
        if (rows != null) {
            rows2List(rows)
        } else {
            coroutineScope.launch {
                viewModel.goodsFromNet().apply {
                    if (success) {
                        Toast.makeText(requireContext(), "商品库同步完成", Toast.LENGTH_LONG).show()
                        kv.encode("rowsList", content)
                        rows2List(content)
                    } else {
                        Toast.makeText(requireContext(), "商品库同步失败 code:$code", Toast.LENGTH_LONG)
                            .show()
                    }
                }
            }
        }

    }


    override fun onPause() {
        super.onPause()
        viewModel.disposable()
        coroutineScope.cancel()
    }

    private fun rows2List(rows: String) {
        try {
            val jsonObject = JSONObject(rows)
            val jsonArray = jsonObject.getJSONArray("rows")
            company = jsonObject.getString("company")
            for (i in 0 until jsonArray.length()) {
                val jsonObject = jsonArray.get(i) as JSONObject
                val rows = rows()
                rows.barcode = jsonObject.getString("b")
                rows.firstName = jsonObject.getString("f")
                rows.name = jsonObject.getString("n").violationsTrim()
                rows.image = jsonObject.getString("p")
                rows.pinYin = jsonObject.getString("py")
                rowsList.add(rows)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        Log.d("rowsList_size", rowsList.size.toString())
    }

    override fun onDestroy() {
        super.onDestroy()
        requireContext().contentResolver.unregisterContentObserver(observer)
    }

}